﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.Composition;
using COFE.Core.Utils;
using COFE.Core.Lister;
using COFE.Core.Filter;
using COFE.Core.Profile;

namespace COFE.Core.Plugin
{
    [Export(typeof(IPluginUser))]
    public class COFEPluginUser : PluginUserBase
    {
        public COFEPluginUser()
            : base(PluginBase.Priority_COFE)
        {

        }

        protected T GetCOFEProperty<T>(IPluginManager manager, Func<ICOFEPlugin, T> propertyGetFunc)           
        {
            return base.GetProperty<ICOFEPlugin, T>(manager, propertyGetFunc);
        }

        protected IEnumerable<T> GetAllCOFEProperty<T>(IPluginManager manager, 
            Func<ICOFEPlugin, IEnumerable<T>> propertyGetFunc)
        {
            return base.GetAllProperty<ICOFEPlugin, T>(manager, propertyGetFunc);
        }

        public override void Apply(IPluginManager manager)
        {
            var m = manager;

            COFEShared.EntryListRegistrar = GetCOFEProperty(m, p => p.EntryListRegistrar);
            COFEShared.UserProfileManager = GetCOFEProperty(m, p => p.UserProfileManager);
            COFEShared.EntryTypeDictionary = GetCOFEProperty(m, p => p.EntryTypeDictionary);
            COFEShared.VolumeRegistrar = GetCOFEProperty(m, p => p.VolumeRegistrar);
            COFEShared.SecondaryPropertyProviderManager = GetCOFEProperty(m, p => p.SecondaryPropertyProviderManager);
            COFEShared.PropertyDictionary = GetCOFEProperty(m, p => p.PropertyDictionary);
            COFEShared.PathParser = GetCOFEProperty(m, p => p.PathParser);
            COFEShared.EntryConstructor = GetCOFEProperty(m, p => p.EntryConstructor);
            COFEShared.FileSystemEventDispatcher = GetCOFEProperty(m, p => p.FileSystemEventDispatcher);

            var fsiEventLogger = GetCOFEProperty(m, p => p.FileSystemEventLogger);
            if (fsiEventLogger != null)                            
                COFEShared.MasterEventLogger.RegisterEventLoggers(fsiEventLogger);            

            COFEShared.VolumeRegistrar.RegisterFactory(
                new ProfileRootDirectoryListerFactory(
                    ProfileRootDirectoryLister.ProfileRootFactoryKey));
            COFEShared.VolumeRegistrar.RegisterVolume(
                ProfileRootDirectoryLister.ProfileRootFactoryKey,
                ProfileRootDirectoryLister.ProfileRootListerKey, VolumeAccessMode.List);

            foreach (var df in GetAllCOFEProperty(m, p => p.DirectoryListerFactories))
                COFEShared.VolumeRegistrar.RegisterFactory(df);
            foreach (var p in GetAllCOFEProperty(m, p => p.Properties))
                COFEShared.PropertyDictionary.RegisterProperty(p);
            foreach (var ef in GetAllCOFEProperty(m, p => p.EntryFilters))
                FilterUtils2<IEntryFilter>.RegisterFilter(ef);
            foreach (var tuple in GetAllCOFEProperty(m, p => p.EntryFilterIconProviders))
                FilterUtils2<IEntryFilter>.RegisterIconProvider(tuple.Item1, tuple.Item2);
            foreach (var lf in GetAllCOFEProperty(m, p => p.LookupFilters))
                FilterUtils2<IOptionFilter>.RegisterFilter(lf);
            foreach (var pp in GetAllCOFEProperty(m, p => p.EntryListPropertyProviders))
                COFEShared.SecondaryPropertyProviderManager.Register(pp); 
            foreach (var pp in GetAllCOFEProperty(m, p => p.EntryPropertyProviders))
                COFEShared.SecondaryPropertyProviderManager.Register(pp);
            foreach (var pp in GetAllCOFEProperty(m, p => p.EventLogPropertyProviders))
                COFEShared.SecondaryPropertyProviderManager.Register(pp); 
        }
    }
}
